package com.hui.operatelog;

import com.hui.auth.config.shiro.SecurityUtil;
import com.hui.auth.dto.JsonResult;
import com.hui.auth.entity.AuthUser;
import com.hui.utils.DateUtil;
import com.hui.operatelog.entity.OperateLog;
import com.hui.operatelog.service.OperateLogService;
import com.hui.utils.HttpRequestUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Date;

/**
 * 操作日志
 *
 * @author 廖云辉
 */
@Aspect
@Component
public class OperateLogAspect {

    @Autowired
    private OperateLogService operateLogService;

    @Pointcut("within(com.hui.auth.web.*)")
    public void controllerLog() {
    }

    @Before("controllerLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {

    }

    /**
     * 成功或失败处理
     */
    @AfterReturning(returning = "ret", pointcut = "controllerLog()")
    public void doAfterReturning(JoinPoint joinPoint, Object ret) throws Throwable {
        AuthUser user = SecurityUtil.currentUser();
        if (null != user) {
            try {
                Signature signature = joinPoint.getSignature();
                MethodSignature methodSignature = (MethodSignature) signature;
                Method method = methodSignature.getMethod();

                if (method.isAnnotationPresent(OperationLog.class)) {
                    OperationLog _log = method.getAnnotation(OperationLog.class);
                    OperateLog log = new OperateLog();
                    log.setOperateType(_log.operation().getKey());
                    log.setOperateContent(_log.content());
                    log.setOperateTime(DateUtil.parseDateToString(new Date()));
                    log.setOperateUser(user.getUserName());
                    log.setOperateUserId(user.getId());
                    log.setIp(HttpRequestUtil.getCurrentRequest().getRemoteHost());
                    if (ret instanceof JsonResult) {
                        JsonResult result = (JsonResult) ret;
                        if (200 == result.getCode()) {
                            log.setOperateResult(OperateResult.SUCCESS.getResult());
                        } else {
                            log.setOperateResult(OperateResult.Failure.getResult());
                        }
                        log.setResultDescription(result.getMsg());
                    }
                    operateLogService.insert(log);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 异常处理
     */
    @AfterThrowing(value = "controllerLog()", throwing = "exception")
    public void doAfterThrowingAdvice(JoinPoint joinPoint, Throwable exception) {
        AuthUser user = SecurityUtil.currentUser();
        try {
            Signature signature = joinPoint.getSignature();
            MethodSignature methodSignature = (MethodSignature) signature;
            Method method = methodSignature.getMethod();

            if (method.isAnnotationPresent(OperationLog.class)) {
                OperationLog _log = method.getAnnotation(OperationLog.class);
                OperateLog log = new OperateLog();
                log.setOperateType(_log.operation().getKey());
                log.setOperateContent(_log.content());
                log.setOperateTime(DateUtil.parseDateToString(new Date()));
                log.setIp(HttpRequestUtil.getCurrentRequest().getRemoteHost());
                if (null != user) {
                    log.setOperateUser(user.getUserName());
                    log.setOperateUserId(user.getId());
                } else {
                    log.setOperateUser("");
                    log.setOperateUserId(0L);
                }
                log.setOperateResult(OperateResult.Failure.getResult());
                log.setResultDescription(exception.toString());
                operateLogService.insert(log);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
